home *** CD-ROM | disk | FTP | other *** search
- /*
- * rings.c - Create objects with 6 pentagonal rings which connect the midpoints
- * of the edges of a dodecahedron. A pyramid of these objects is formed,
- * which the viewer looks upon from the point. A plane is placed behind
- * the pyramid for shadows. No object is clipped. Three light sources.
- *
- * Version: 2.2 (11/17/87)
- * Author: Eric Haines, 3D/Eye, Inc.
- *
- * SIZE_FACTOR determines the number of objects output.
- * Each object has 30 cylinders and 30 spheres.
- * Total objects = SF*SF + (SF-1)*(SF-1) + ... + 1 plus 1 backdrop square.
- * formula for # of spheres or cylinders = 5*SF*(SF+1)*(2*SF+1)
- *
- * SIZE_FACTOR # spheres # cylinders # squares
- * 1 30 30 1
- * 2 150 150 1
- * 3 420 420 1
- *
- * 7 4200 4200 1
- */
-
- #include <stdio.h>
- #include <math.h>
- #ifdef MAC
- #include <console.h>
- #endif
-
- #include "def.h"
- #include "lib.h"
-
- #define SIZE_FACTOR 2
-
- /* if spread out is > 1, succeeding layers spread out more */
- #define SPREAD_OUT 1
-
- /* Create the set of 30 points needed to generate the rings */
- static void
- create_dodec(double minor_radius, COORD4 vertex[30])
- {
- long num_vertex, num_pentagon ;
- COORD4 temp_vertex ;
- MATRIX x_matrix, z_matrix ;
- double scale, x_rotation, z_rotation ;
-
-
- /* scale object to fit in a sphere of radius 1 */
-
- scale = 1.0 / ( 1.0 + minor_radius ) ;
- /*
- * define one pentagon as on the XY plane, with points starting along +X
- * and N fifths of the way around the Z axis.
- */
- for ( num_vertex = 0 ; num_vertex < 5 ; ++num_vertex ) {
- vertex[num_vertex].x = scale * cos( (double)num_vertex * 2.0*PI/5.0 ) ;
- vertex[num_vertex].y = scale * sin( (double)num_vertex * 2.0*PI/5.0 ) ;
- vertex[num_vertex].z = 0.0 ;
- vertex[num_vertex].w = 1.0 ;
- }
-
- /*
- * find the rotation angle (in radians) along the X axis:
- * angle between two adjacent dodecahedron faces.
- */
- x_rotation = 2.0 *
- acos( cos( (double)(PI/3.0) ) / sin( (double)(PI/5.0) ) ) ;
- lib_create_rotate_matrix( x_matrix, X_AXIS, x_rotation ) ;
-
- /*
- * Find each of the other 5 pentagons: rotate along the X axis,
- * then rotate on the Z axis.
- */
- for ( num_pentagon = 1 ; num_pentagon < 6 ; ++num_pentagon ) {
- /*
- * find the rotation angle (in radians) along the Z axis:
- * 1/10th plus N fifths of the way around * 2 * PI.
- */
- z_rotation = PI*( 2.0*(double)(num_pentagon-1)+1.0 ) / 5.0 ;
- lib_create_rotate_matrix( z_matrix, Z_AXIS, z_rotation ) ;
-
- for ( num_vertex = 0 ; num_vertex < 5 ; ++num_vertex ) {
-
- lib_transform_coord( &temp_vertex
- , &vertex[num_vertex]
- , x_matrix
- ) ;
-
- lib_transform_coord( &vertex[5*num_pentagon+num_vertex]
- , &temp_vertex
- , z_matrix
- ) ;
- }
- }
- }
-
- void
- main(int argc, char *argv[])
- {
- COORD4 base_pt, apex_pt, offset ;
- COORD4 wall[4], dodec[30] ;
- COORD4 from, at, up, dir;
- COORD4 wvec, light ;
- COORD4 back_color, ring_color[6] ;
- long prev_elem ;
- long num_elem ;
- long num_depth, num_objx, num_objz ;
- double radius ;
- double spread, y_diff, xz_diff ;
- char *txname, *c[6];
- int cind = 0;
-
- #ifdef MAC
- argc = ccommand(&argv);
- #endif
-
-
- radius = 0.07412 ; /* cone and sphere radius */
-
- /* calculate spread of objects */
- spread = 1 / sin( (double)( PI/8.0 ) ) ;
- if ( SPREAD_OUT <= spread ) {
- y_diff = spread / SPREAD_OUT ;
- xz_diff = 1.0 ;
- }
- else {
- y_diff = 1.0 ;
- xz_diff = SPREAD_OUT / spread ;
- }
-
- /* output viewpoint */
- SET_COORD( from, -1.0, -spread, 0.5 ) ;
- SET_COORD( at, from.x, from.y + 1.0, from.z ) ;
- SET_COORD( up, 0.0, 0.0, 1.0 ) ;
- lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
-
- /* output background color - UNC sky blue */
- /* note that the background color should never be seen */
- SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
- lib_output_background_color( &back_color ) ;
-
- /* output light source */
- SET_COORD( light, 3.0, -spread, 3.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, -4.0, -spread, 1.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, 2.0, -spread, -4.0 ) ;
- lib_output_light( &light ) ;
-
- /* Output bounding slabs oriented along the coordinate axes */
- SET_COORD(dir, 1.0, 0.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 1.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 0.0, 1.0);
- lib_output_bounding_slab(&dir);
-
- /* output wall polygon - white */
- SET_COORD( back_color, 1.0, 1.0, 1.0 ) ;
- txname = lib_output_color(&back_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
- /* just spans 45 degree view + 1% */
- wvec.y = y_diff * ( SIZE_FACTOR + 1 ) ;
- wvec.x = wvec.z = 1.01 * ( wvec.y - from.y ) * tan( PI / 8.0 ) ;
- SET_COORD( wall[0], wvec.x+from.x, wvec.y, wvec.z+from.z ) ;
- SET_COORD( wall[1], -wvec.x+from.x, wvec.y, wvec.z+from.z ) ;
- SET_COORD( wall[2], -wvec.x+from.x, wvec.y, -wvec.z+from.z ) ;
- SET_COORD( wall[3], wvec.x+from.x, wvec.y, -wvec.z+from.z ) ;
- lib_output_polygon(4, wall, txname);
-
- /* set up ring colors - RGB and complements */
- SET_COORD(ring_color[0], 1.0, 0.0, 0.0);
- SET_COORD(ring_color[1], 0.0, 1.0, 0.0);
- SET_COORD(ring_color[2], 0.0, 0.0, 1.0);
- SET_COORD(ring_color[3], 0.0, 1.0, 1.0);
- SET_COORD(ring_color[4], 1.0, 0.0, 1.0);
- SET_COORD(ring_color[5], 1.0, 1.0, 0.0);
- c[0] = lib_output_color(&ring_color[0], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
- c[1] = lib_output_color(&ring_color[1], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
- c[2] = lib_output_color(&ring_color[2], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
- c[3] = lib_output_color(&ring_color[3], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
- c[4] = lib_output_color(&ring_color[4], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
- c[5] = lib_output_color(&ring_color[5], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
-
- create_dodec( radius, dodec ) ;
- /* radius of osculating cylinders and spheres (no derivation given) */
- base_pt.w = apex_pt.w = radius ;
-
- for ( num_depth = 0 ; num_depth < SIZE_FACTOR ; ++num_depth ) {
- offset.y = y_diff * (double)(num_depth+1) ;
- for ( num_objz = 0 ; num_objz <= num_depth ; ++num_objz ) {
- offset.z = xz_diff * (double)(2*num_objz - num_depth) ;
- for ( num_objx = 0 ; num_objx <= num_depth ; ++num_objx ) {
- offset.x = xz_diff * (double)(2*num_objx - num_depth) ;
- for ( num_elem = 0 ; num_elem < 30 ; ++num_elem ) {
- COPY_COORD( base_pt, dodec[num_elem] ) ;
- ADD2_COORD( base_pt, offset ) ;
- if ( num_elem%5 == 0 ) {
- prev_elem = num_elem + 4 ;
- /* new ring beginning - output color */
- cind = num_elem/5;
- }
- else {
- prev_elem = num_elem - 1 ;
- }
- COPY_COORD( apex_pt, dodec[prev_elem] ) ;
- ADD2_COORD( apex_pt, offset ) ;
-
- lib_output_cylcone( &base_pt, &apex_pt, c[cind]);
- lib_output_sphere( &base_pt, c[cind]);
- }
- }
- }
- }
- }
-